package com.xtiim.battery.discharge.modules.htm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.xtiim.battery.discharge.modules.htm.mapper.HostInfoMapper;
import com.xtiim.battery.discharge.modules.htm.model.HostInfo;
import com.xtiim.battery.discharge.modules.htm.param.HostInfoCreatParam;
import com.xtiim.battery.discharge.modules.htm.param.HostInfoQueryParam;
import com.xtiim.battery.discharge.modules.htm.param.HostInfoUpdateParam;
import com.xtiim.battery.discharge.modules.htm.service.HostInfoService;
import com.xtiim.battery.discharge.persistence.IPage;
import com.xtiim.battery.discharge.persistence.MybatisUtil;
import com.xtiim.battery.discharge.persistence.Page;
import com.xtiim.battery.discharge.protocal.manager.HostManager;
import com.xtiim.battery.discharge.util.PageUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

/**
 * HostInfoServiceImpl, singleton
 */
public class HostInfoServiceImpl implements HostInfoService {

    private static final HostInfoService instance = new HostInfoServiceImpl();

    private HostInfoServiceImpl() {
    }

    public static HostInfoService getInstance() {
        return instance;
    }

    @Override
    public Boolean create(HostInfoCreatParam createParam) {
        SqlSession sqlSession = null;
        try {
            sqlSession = MybatisUtil.getSqlSession();
            HostInfoMapper hostInfoMapper = sqlSession.getMapper(HostInfoMapper.class);

            HostInfo hostInfo = new HostInfo();
            BeanUtil.copyProperties(createParam, hostInfo);
            Boolean result = hostInfoMapper.insert(hostInfo);
            sqlSession.commit();

            HostManager.getInstance().addHost(hostInfo.getNumber(), hostInfo);

            return result;
        } catch (Exception e) {
            sqlSession.rollback();
            throw e;
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }

    @Override
    public HostInfo selectHostInfo(String name, String number) {
        try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
            HostInfoMapper hostInfoMapper = sqlSession.getMapper(HostInfoMapper.class);
            return hostInfoMapper.selectHostInfo(name, number);
        } catch (Exception e) {
            throw e;
        }
    }

    @Override
    public Boolean update(HostInfoUpdateParam updateParam) {
        SqlSession sqlSession = null;
        try {
            sqlSession = MybatisUtil.getSqlSession();
            HostInfoMapper hostInfoMapper = sqlSession.getMapper(HostInfoMapper.class);

            HostInfo hostInfo = new HostInfo();
            BeanUtil.copyProperties(updateParam, hostInfo);
            Boolean result = hostInfoMapper.update(hostInfo);
            sqlSession.commit();

            return result;
        } catch (Exception e) {
            sqlSession.rollback();
            throw e;
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }

    @Override
    public <T> T getHostInfo(HostInfoQueryParam queryParam) {
        if (queryParam.getUsePage()) {
            Integer pageNo = queryParam.getPageNo();
            Integer pageSize = queryParam.getPageSize();
            PageUtil.validatePageParams(pageNo, pageSize);
            IPage<HostInfo> page = null;
            try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
                HostInfoMapper hostInfoMapper = sqlSession.getMapper(HostInfoMapper.class);
                Integer total = hostInfoMapper.getHostInfoCount(queryParam);
                Integer offset = (pageNo - 1) * pageSize;
                List<HostInfo> hostInfos = hostInfoMapper.getHostInfoPage(queryParam, offset, pageSize);
                if (CollectionUtil.isEmpty(hostInfos)) {
                    return (T) PageUtil.emptyPage(pageNo, pageSize);
                }
                page = new Page(hostInfos, total, PageUtil.totalPage(total, pageSize), pageSize, pageNo);
                return (T) page;
            } catch (Exception e) {
                throw e;
            }
        } else {
            try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
                HostInfoMapper hostInfoMapper = sqlSession.getMapper(HostInfoMapper.class);
                List<HostInfo> allHostInfos = hostInfoMapper.getAllHostInfos();
                return (T) allHostInfos;
            } catch (Exception e) {
                throw e;
            }
        }
    }

    @Override
    public Boolean deleteHostInfo(Long id) {
        SqlSession sqlSession = null;
        try {
            sqlSession = MybatisUtil.getSqlSession();
            HostInfoMapper hostInfoMapper = sqlSession.getMapper(HostInfoMapper.class);

            HostInfo hostInfo = hostInfoMapper.getHostInfoById(id);

            Boolean result = hostInfoMapper.delete(id);
            sqlSession.commit();

            HostManager.getInstance().removeHost(hostInfo.getNumber());
            return result;
        } catch (Exception e) {
            sqlSession.rollback();
            throw e;
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }

    @Override
    public List<HostInfo> getAllOpenedHostInfos() {
        try (SqlSession sqlSession = MybatisUtil.getSqlSession()) {
            HostInfoMapper hostInfoMapper = sqlSession.getMapper(HostInfoMapper.class);
            return hostInfoMapper.getAllOpenedHostInfos();
        } catch (Exception e) {
            throw e;
        }
    }

}
